package org.leiyang.controller;

import io.netty.util.internal.StringUtil;
import org.leiyang.common.dtos.LoginUser;
import org.leiyang.common.dtos.R;
import org.leiyang.common.dtos.UserInfoDTO;
import org.leiyang.common.entities.User;
import org.leiyang.common.util.TokenUtil;
import org.leiyang.domains.dtos.LoginVO;
import org.leiyang.domains.dtos.UserList;
import org.leiyang.repository.UserRepository;
import org.leiyang.service.impl.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Collectors;

import static org.leiyang.common.util.Constants.*;

@RestController
@RequestMapping("/user")
public class UserController {
    private static final Logger log = LoggerFactory.getLogger(UserController.class);
    private final UserService userService;
    private final UserRepository userRepository;

    public UserController(UserService userService, UserRepository userRepository) {
        this.userService = userService;
        this.userRepository = userRepository;
    }

    /**
     * 获取所有的用户
     */
    @GetMapping("/all")
    public Flux<UserList> getAllUser(@RequestHeader(DETAILS_USER_ID) Long uid) {
        return userService.listAllUsers(uid);
    }

    /**
     * 批量获取用户信息
     * @param uIds 用户ID集合（逗号分隔）
     * @return 用户列表
     */
    @GetMapping("/list/ids")
    public Flux<User> listUsersByIds(String uIds) {
        log.info("/list/ids接口的入参: {}", uIds);
        if(StringUtil.isNullOrEmpty(uIds)) {
            return Flux.empty();
        }
        return userRepository.listUsersByIds(Arrays.stream(uIds.split(","))
                .collect(Collectors.toList())
        );
    }

    /**
     * 登录接口
     * @return access token
     */
    @PostMapping("/login")
    public Mono<R<String>> login(@RequestBody LoginVO form, @RequestHeader(CLIENT_IP) String clientIp) {
        return userService.login(form, clientIp);
    }

    /**
     * 获取当前登录用户的信息
     * @param uid 用户ID
     */
    @GetMapping("/current/info")
    public Mono<R<UserInfoDTO>> getCurrentUserInfo(@RequestHeader(DETAILS_USER_ID) Long uid) {
        return userService.getCurrentUserInfo(uid);
    }

    /**
     * 退出登录
     */
    @PostMapping("/logout")
    public Mono<R<Boolean>> logout(@RequestHeader(USER_KEY) String accessToken,
                                @RequestHeader(CLIENT_IP) String clientIp,
                                @RequestHeader(DETAILS_USER_ID) Long uid) {
        log.info("本次执行logout接口的入参, token: {}, clientIp: {}, uid: {}", accessToken, clientIp, uid);
        //由于{@link org.leiyang.gateway.Filters.InnerFilter.addHeader}进行了编码处理，所以此处需要进行解码处理
//        String token = UriUtils.decode(accessToken, Charset.defaultCharset());
//        log.info("解码之后的token: {}", token);
        //对token无需进行解码操作
        return userService.logout(accessToken, clientIp, uid);
    }

    /**
     * 从token里解析出用户信息
     */
    @GetMapping("/decrypt")
    public Mono<LoginUser> decryptPBE(String token) {
        if(StringUtil.isNullOrEmpty(token)) {
            return Mono.empty();
        }
//        log.info("本次收到的解析前的token: {}", token);
        return Mono.just(Objects.requireNonNull(TokenUtil.parseToken(token)));
    }
}